package com.jsaas.plugin.generator;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import javax.sql.DataSource;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.activerecord.generator.ColumnMeta;
import com.jfinal.plugin.activerecord.generator.MetaBuilder;
import com.jfinal.plugin.activerecord.generator.TableMeta;

/**   
* @Title: MetaBuilderExt.java 
* @Package com.jsaas.plugin.generator 
* @Description: TODO(用一句话描述该文件做什么) 
* @author tuozq 
* @date 2017年11月27日 下午1:51:40 
* @version V1.0   
*/
public class MetaBuilderExt extends MetaBuilder {
	
	protected Set<String> includedTables = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

	public MetaBuilderExt(DataSource dataSource) {
		super(dataSource);
		// TODO Auto-generated constructor stub
	}
	
	public void setIncludedTables(Set<String> includedTables){
		this.includedTables = includedTables;
	}
	
	public void setIncludedTables(String... tables){
		Set<String> set = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
		for (String table : tables) {
			set.add(table);
		}
		setIncludedTables(set);
	}
	
	@Override
	protected void buildTableNames(List<TableMeta> ret) throws SQLException {
		// TODO Auto-generated method stub
		ResultSet rs = getTablesResultSet();
		while (rs.next()) {
			String tableName = rs.getString("TABLE_NAME");
			
			if (!includedTables.contains(tableName) || excludedTables.contains(tableName)) {
				//System.out.println("Skip table :" + tableName);
				continue ;
			}
			if (isSkipTable(tableName)) {
				System.out.println("Skip table :" + tableName);
				continue ;
			}
			
			TableMeta tableMeta = new TableMeta();
			tableMeta.name = tableName;
			tableMeta.remarks = rs.getString("REMARKS");
			
			tableMeta.modelName = buildModelName(tableName);
			tableMeta.baseModelName = buildBaseModelName(tableMeta.modelName);
			ret.add(tableMeta);
		}
		rs.close();
	}
	
	@Override
	protected String buildModelName(String tableName) {
		tableName = tableName.toLowerCase();
		
		if (removedTableNamePrefixes != null) {
			for (String prefix : removedTableNamePrefixes) {
				if (tableName.startsWith(prefix.toLowerCase())) {
					tableName = tableName.replaceFirst(prefix, "");
					break;
				}
			}
		}
		return StrKit.firstCharToUpperCase(StrKit.toCamelCase(tableName));
	}
	
	@Override
	protected void buildColumnMetas(TableMeta tableMeta) throws SQLException {
		String sql = dialect.forTableBuilderDoBuild(tableMeta.name);
		Statement stm = conn.createStatement();
		ResultSet rs = stm.executeQuery(sql);
		ResultSetMetaData rsmd = rs.getMetaData();
		
		for (int i=1; i<=rsmd.getColumnCount(); i++) {
			ColumnMeta cm = new ColumnMeta();
			cm.name = rsmd.getColumnName(i);
			String typeStr = null;
			if (dialect.isKeepByteAndShort()) {
				int type = rsmd.getColumnType(i);
				if (type == Types.TINYINT) {
					typeStr = "java.lang.Byte";
				} else if (type == Types.SMALLINT) {
					typeStr = "java.lang.Short";
				}
			}
			
			if (typeStr == null) {
				String colClassName = rsmd.getColumnClassName(i);
				typeStr = typeMapping.getType(colClassName);
			}
			
			if (typeStr == null) {
				int type = rsmd.getColumnType(i);
				if (type == Types.BINARY || type == Types.VARBINARY || type == Types.LONGVARBINARY || type == Types.BLOB) {
					typeStr = "byte[]";
				} else if (type == Types.CLOB || type == Types.NCLOB) {
					typeStr = "java.lang.String";
				} else {
					typeStr = "java.lang.String";
				}
			}
			cm.javaType = typeStr;
			
			// 鏋勯�瀛楁瀵瑰簲鐨勫睘鎬у悕 attrName
			if(cm.name.startsWith("CF")){
				cm.attrName = buildAttrName(cm.name.replaceFirst("CF", ""));
			}else{
				cm.attrName = buildAttrName(cm.name);
			}
			
			tableMeta.columnMetas.add(cm);
		}
		
		rs.close();
		stm.close();
	}

}
